module hope_mod
  use gptl_timer_mod
  use spark_cubed_sphere
  use params_mod
  use time_mod, old => old_time_idx, new => new_time_idx
  use time_schemes_mod
  use dycore_mod
  use test_mod
  use history_mod

  implicit none

  private

  public hope_init
  public hope_run
  public hope_final

contains

  subroutine hope_init(namelist_file, comm)

    character(*), intent(in)           :: namelist_file
    integer     , intent(in), optional :: comm

    call gptl_timer_init
    call log_init()
    call spark_init()
    call params_init(namelist_file)
    call time_init(dt, start_time, end_time)
    call proc%init(comm)
    call proc%decomp_domain(mesh, proj_type=equiangular, hdim=hdim, vdim=vdim, nc=nc, nz=nz, hw=hw, rw=rw, rwv=min(rwv,3), neq=neq)
    call time_schemes_init()
    call dycore_init(mesh)
    call test_setup(case_id, static, state(old), diag)
    call history_init(static, state(old), diag, tend(old))

    call time_add_alert('print', seconds=print_interval)
    
  end subroutine hope_init

  subroutine hope_run()
    
    call dycore_diag_fields(state(old), diag)
    call dycore_diag_scalars(state(old), diag, static)
    call history_write(elapsed_seconds, state(old), diag, tend(old))
    
    do while (.not. time_is_finished())
      if (time_is_alerted('print')) then
        call log_print_diag(curr_time%isoformat(), pid=proc%id)
      end if
      
      call dycore_run(old, new, dt)
      
      call time_advance()
      
      if ( time_is_alerted('print') .or. time_is_alerted('history') ) then
        call dycore_diag_fields(state(old), diag)
        call dycore_diag_scalars(state(old), diag, static)
      end if
      
      call history_write(elapsed_seconds, state(old), diag, tend(old))
    end do
    
    call log_print_diag(curr_time%isoformat(), pid=proc%id)
    
  end subroutine hope_run

  subroutine hope_final()

    call dycore_final()
    call spark_final()
    call gptl_timer_final

  end subroutine hope_final

end module hope_mod
